CHAPTER 3

VB Syntax

This chapter is an introduction to the syntax of the Visual Basic (VB) language. The topics covered here are the glue that binds programs together. We’ll take a close look at types and variables, since the common type system (CTS) is a key component of the .NET common language runtime (CLR). By the same token, the type system is one facet of VB that is very different in .NET from previous versions. We’ll also look at namespaces; this is a .NET concept you’ll put into practice as soon as you write your first program. Understanding namespaces not only helps you navigate the VB namespaces to find the classes you need, but it also helps you to create your own namespaces in a logical manner. We’ll wrap up with an overview of VB control flow statements, which differ in syntax but are the same in concept across all lan-guages.

In this chapter, we assume you have some experience with a previous version of VB. Although it’s obvious that the VB language was designed to leverage the knowledge of VB developers, you’ll notice that it’s quite a departure from Visual Basic 6 (VB6). If you’re coming from a VB6 development background, some of the new language features may be new to you, but it won’t be long before you feel right at home with VB syntax.

Types and Variables

Types in VB can be either value types or reference types. Value types, such as structures and built-in types, are allocated on the stack and contain their associated data. Reference types, such as classes and arrays, are allocated on the managed heap, while a reference (pointer) to the object is stored on the stack. As we progress through this chapter, we’ll discuss types and variables in more detail. Chapters 4 and 5 will continue the discussion in greater depth.

Strong Typing

VB is a strongly typed language. Well, to be more precise, VB can be a strongly typed language. Strong typing means that every variable and object instance that’s declared must be of a well-defined type. A strongly typed language provides rules for how variables of different types can interact with each other. Strongly typed variables enable the compiler to check that the opera-tions being performed on variables and objects are valid. For example, suppose you have a method that computes the average of two integers and returns the result. The method is declared in VB as follows:

Function ComputeAvg(ByVal Param1 As Integer, ByVal Param2 As Integer) As Double
    ComputeAvg = (Param1 + Param2) / 2
End Function

This method accepts two integers and returns a double. Therefore, if you attempt to call this method and pass in two Customer objects, you’ll receive a compile-time error. Now, let’s write the method slightly differently:

Function ComputeAvg(ByVal Param1 As Object, ByVal Param2 As Object) As Object
    ComputeAvg = (Convert.ToInt32(Param1) + Convert.ToInt32(Param2)) / 2
End Function

The second version of ComputeAvg() is still valid, but you have forcefully stripped away the type information. You could pass in String, Boolean, or Customer objects, and you wouldn’t receive an error until run time when the function attempts to convert the parameters. This is because every object and value in VB derives from System.Object. The Objectkeyword in VB is an alias for the class System.Object. It’s perfectly valid to declare parameters as type Object; however, Object is not a numeric type. In order to perform the calculation, you must first “cast” the objects into integers. The result is also returned as an instance of type Object. If you attempt to pass two Customer objects, the compiler won’t return an error because those objects both derive from System.Object, as every other class does. Although this version of the method seems more flexible, this flexibility comes at the price of type safety and performance.

Needless to say, it’s always best to find bugs at compile time rather than run time. If you were to use the first version of ComputeAvg() and try to pass in anything other than integers, you wouldn’t be able to compile the application. Type safety is one of the tenets of develop-ment in .NET, and the language is designed to support it.

The reason I say that VB can be strongly typed is that, in contrast to C#, it supports unde-clared variables. This means you can reference a variable without first declaring it with a Dim, Private, or Public declaration. VB will create any undeclared variables as type Object. The two settings that affect strong typing and variable declaration in VB are Option Explicit and Option Strict.

Option Explicit: Option Explicit enforces the declaration of variables. When Option Explicit is set On within a file, any variable must be explicitly declared. If Option Explicit is On and you have an undeclared variable, you’ll receive a compiler error. If Option Explicit isn’t specified in the file, the compiler default is On. In this snippet, you’ll receive a compiler error on the last line, because the variable VarUndeclared is not declared any-where. If Option Explicit was Off, both the variables VarDeclaredand VarUndeclared would be valid. When this code compiles, VB will define VarUndeclared as type Object until it’s assigned, at which point it will implicitly convert it to a Double because of its data assignment:

Option Explicit On

Dim VarDeclared As Double

VarDeclared = ComputeAvg(108, 7933)
VarUndeclared = ComputeAvg(108, 7933)

Option Strict: The Option Strict setting is related to any implicit data conversions that VB performs on variables. Option Strict only allows widening conversions. If Option Strict is On, VB will only allow variables to be converted from one data type to another data type in which no data loss would occur. If a variable is being converted and the resultant type has less precision or smaller capacity, a compiler error will be generated. Option Strict also disallows late binding. If Option Strict isn’t specified, the compiler default is Off. Using the second ComputeAvg function shown previously, you can see that the following code will fail at compile time because Option Strictwon’t allow an implicit conversion from Object to Double. If Option Strict was Off, this code would compile and run:

Option Strict On

Dim x As Double = 0.0

x = ComputeAvg(108, 7933)

Function ComputeAvg(ByVal Param1 As Object, ByVal Param2 As Object) As Object
    ComputeAvg = (Convert.ToInt32(Param1) + Convert.ToInt32(Param2)) / 2
End Function

You should always keep Option Explicitand Option Strict set to On in your applica-tions, primarily because you’ll avoid having to debug some devious errors that only appear at run time. This practice ensures that your code is strongly typed and is consistent with the type safety of other .NET languages.

Note: In VB6, you may have used the Variant data type to store and pass parameters of different data types, because a Variant variable can hold data of any type. Also, if you used undeclared variables, VB6 would create them as Variant. This data type is no longer supported in .NET, and the Object type is used instead.